const util = require('../../utils/util');
const { v4: uuidv4 } = require('uuid');
// 创建 Keyv 存储（可以换成 Redis、MySQL）
const { Keyv } = require('keyv');
const captchaStore = new Keyv();
const userService = require('../../service/system/login.service');
const ConfigService = require('../../service/system/config.service');
const { generateCaptchaImage, verifyCaptchaPosition } = require('../../utils/captchaUtils');
const { aesEncrypt, aesDecrypt } = require('../../utils/encryption');
const bcrypt = require('bcryptjs');
const config = require('../../config');
const tokenBlacklist = new Keyv();
/**
 * 获取验证码是否启用
 */

async function captchaStatus(ctx) {
  try {
    const configValue = await ConfigService.getConfigValue('sys.captcha.state');
    const isCaptchaEnabled = configValue.toLowerCase() == 'true';
    util.success(ctx, isCaptchaEnabled);
  } catch (error) {
    util.fail(ctx, `获取验证码状态失败: ${error.message}`);
  }
}

/**
 * 获取滑块验证码
 */
async function getCaptcha(ctx) {
  try {
    const { bigImageBase64, smallImageBase64, posX, posY, bigWidth } = await generateCaptchaImage();
    const requestId = uuidv4();
    const secretKey = uuidv4().replace(/-/g, '').slice(0, 16);

    // 清除可能存在的旧验证码
    await captchaStore.delete(requestId);

    // 设置新验证码（5分钟过期）
    await captchaStore.set(requestId, { posX, posY, secretKey }, 300000);

    util.success(ctx, {
      requestId,
      bigImageBase64,
      smallImageBase64,
      posY,
      bigWidth,
      secretKey
    });
  } catch (error) {
    console.error('验证码生成错误:', error);
    util.fail(ctx, '验证码生成失败');
  }
}

async function verifyCaptcha(ctx) {
  try {
    const { requestId, moveEncrypted, iv, startTime } = ctx.request.body;
    if (!requestId || !moveEncrypted || !iv || !startTime) {
      return util.fail(ctx, '参数缺失');
    }

    // 验证 IV 长度
    let ivBuffer;
    try {
      ivBuffer = Buffer.from(iv, 'base64');
      if (ivBuffer.length !== 12) {
        // GCM 要求 12 字节 IV
        return util.fail(ctx, '无效的初始化向量长度');
      }
    } catch (error) {
      console.error('IV 解码失败:', error.message);
      return util.fail(ctx, '无效的初始化向量格式');
    }

    // 获取验证码数据
    const captchaData = await captchaStore.get(requestId);
    if (!captchaData) {
      return util.fail(ctx, '验证码已失效，请刷新');
    }

    // 检查验证时间
    const currentTime = Date.now();
    if (currentTime - startTime > 60 * 1000) {
      await captchaStore.delete(requestId);
      return util.fail(ctx, '验证超时，请刷新');
    }

    // 验证 secretKey 长度
    if (captchaData.secretKey.length !== 16) {
      await captchaStore.delete(requestId);
      return util.fail(ctx, '验证失败，请刷新');
    }

    // 解密用户滑动位置
    let decryptedX;
    try {
      decryptedX = aesDecrypt(moveEncrypted, captchaData.secretKey, iv);
    } catch (error) {
      console.error('AES 解密失败:', error.message);
      return util.fail(ctx, '验证失败，请刷新');
    }

    const decryptedMoveX = parseInt(decryptedX, 10);
    if (isNaN(decryptedMoveX)) {
      return util.fail(ctx, '验证失败，请刷新');
    }

    // 进行位置校验
    const isVerified = verifyCaptchaPosition(decryptedMoveX, captchaData.posX);
    if (!isVerified) {
      return util.fail(ctx, '验证失败，请重试');
    }

    // 计算验证耗时
    const duration = ((currentTime - startTime) / 1000).toFixed(2);

    // 删除已使用验证码
    await captchaStore.delete(requestId);

    // 返回成功响应
    util.success(ctx, `验证成功，耗时 ${duration}s`);
  } catch (error) {
    console.error('验证验证码失败:', error);
    util.fail(ctx, '验证失败');
  }
}

/**
 * 用户登录
 */
async function login(ctx) {
  const { username, password } = ctx.request.body;
  if (!username || !password) return util.fail(ctx, '请填写完整信息！');
  // 根据用户名查询用户（包含哈希密码）
  const user = await userService.findUser(username);
  if (!user) {
    util.fail(ctx, '用户名或密码错误');
    return;
  }
  // 使用 BCrypt 验证密码
  const isMatch = await bcrypt.compare(password, user.pwd);
  if (!isMatch) {
    util.fail(ctx, '用户名或密码错误');
    return;
  }
  const token = util.createToken({ username, userId: user.id });
  userService.updateLoginTime(user.id);
  const configVal = await ConfigService.getConfigValue(['sys_dept_entityName', 'sys_footerText']);
  const userInfo = await userService.findUserInfo(username);
  userInfo.sys_dept_entityName = configVal['sys_dept_entityName'];
  userInfo.sys_footerText = configVal['sys_footerText'];
  util.success(ctx, { accessToken: token, userInfo });
}

//退出登录
async function logout(ctx) {
  try {
    // 从请求头或 ctx 中获取 Token
    const token = ctx.headers['authorization']?.replace('Bearer ', '');
    if (!token) {
      return util.fail(ctx, '未提供 Token');
    }
    // 将 Token 加入黑名单，设置过期时间（与 Token 有效期一致，或自定义）
    await tokenBlacklist.set(token, 'invalid', config.JWT_EXPIRES_IN);
    util.success(ctx, '退出成功');
  } catch (error) {
    util.fail(ctx, `退出失败: ${error.message}`);
  }
}

module.exports = {
  captchaStatus,
  getCaptcha,
  verifyCaptcha,
  login,
  logout
};
